package com.tarena.luban.worker.server.service;

import com.tarena.luban.worker.server.bo.*;
import com.tarena.luban.worker.server.repo.WorkerAreaRepository;
import com.tarena.luban.worker.server.repo.WorkerCategoryRepository;
import com.tarena.luban.worker.server.repo.WorkerRepository;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.dto.AttachDTO;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.attach.server.query.AttachQuery;
import com.tarena.tp.luban.account.server.client.AccountApi;
import com.tarena.tp.luban.account.server.dto.AccountDTO;
import com.tarena.tp.luban.worker.server.common.enums.ResultEnum;
import com.tarena.tp.luban.worker.server.dto.dto.WorkerDTO;
import com.tarena.tp.luban.worker.server.dto.param.IdCardParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCreateParam;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class WorkerServerService {
    //定义三个不同的仓库层对象
    @Autowired
    private WorkerRepository workerRepository;
    @Autowired
    private WorkerAreaRepository workerAreaRepository;
    @Autowired
    private WorkerCategoryRepository workerCategoryRepository;
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        //1. userId
        Long userId=getUserIdFromToken();
        workerCreateParam.setUserId(userId);
        //2. 检查参数 idCard phone
        checkPhoneAndIdCard(workerCreateParam);
        //3. 新增
        Long id=saveWorker(workerCreateParam);
        // id 没有给下面2个参数传递
        saveWorkerArea(workerCreateParam);
        saveWorkerCategory(workerCreateParam);
        return id;
    }
    private void saveWorkerCategory(WorkerCreateParam workerCreateParam) {
        //delete from worker_category where user_id=#{userId}
        workerCategoryRepository.deleteWorkerCategory(workerCreateParam.getUserId());
        workerCategoryRepository.saveWorkerCategory(workerCreateParam);
    }

    private void saveWorkerArea(WorkerCreateParam workerCreateParam) {
        //delete from worker_area where user_id=#{userId}
        workerAreaRepository.deleteWorkerArea(workerCreateParam.getUserId());
        workerAreaRepository.saveWorkerArea(workerCreateParam);
    }
    public static final Integer BYZ_TYPE=100;
    @Autowired
    private AttachApi attachApi;
    private Long saveWorker(WorkerCreateParam workerCreateParam) {
        //先将数据库里 绑定userId的师傅信息删除
        workerRepository.deleteWorker(workerCreateParam.getUserId());
        //新增同时,返回新增id值
        Long id=workerRepository.saveWorker(workerCreateParam);
        //绑定图片
        //为调用接口准备一个对象
        List<AttachUpdateParam> updateParams=new ArrayList<>();
        for (IdCardParam idCardParam : workerCreateParam.getAttachList()) {
            AttachUpdateParam attachUpdateParam=new AttachUpdateParam();
            attachUpdateParam.setId(idCardParam.getId());//图片id
            attachUpdateParam.setIsCover(idCardParam.getType());//可以不给
            attachUpdateParam.setBusinessId(id.intValue());//师傅入驻生成的id
            attachUpdateParam.setBusinessType(BYZ_TYPE);
            updateParams.add(attachUpdateParam);
        }
        attachApi.batchUpdateAttachByIdList(updateParams);

        List<IdCardParam> attachList = workerCreateParam.getAttachList();
        //dubbo远程调用 绑定图片
        return id;
    }

    private void checkPhoneAndIdCard(WorkerCreateParam workerCreateParam) {
        log.info("测试阶段,检查了电话号码和身份证号");
    }

    private Long getUserIdFromToken() throws BusinessException {
        //直接调用SDK的api 解析拿到User对象 LoginUser
        LoginUser loginUser = SecurityContext.getLoginToken();
        //处理一下异常逻辑--自定义的业务异常 loginUser不一定存在,因为可能没登录
        if (loginUser== null){
            throw new BusinessException(ResultEnum.USER_TOKEN_VERIFY_FAILED);
        }
        return loginUser.getUserId();
    }

    /**
     * 师傅数据 worker
     * 师傅区域数据 worker_area
     * 师傅种类数据 worker_category
     * 师傅账号数据 account中心 TODO
     * 师傅图片数据 attach中心 dubbo远程调用
     * 1. userId获取
     * 2. 利用userId查询到师傅对象
     * 3. 师傅不为空的时候
     * 3.1 查询对应区域
     * 3.2 查询对应种类
     * 3.3 TODO 查询account
     * 3.4 查询图片
     * 4 return null;
     */
    @Autowired
    private AccountApi accountApi;
    public WorkerBO detail() throws BusinessException {
        Long userId=getUserIdFromToken();
        //需要在Repository实现po和bo转化
        long start= System.currentTimeMillis();
        WorkerBO workerBO=getWorkerByUserId(userId);
        long end= System.currentTimeMillis();
        log.info("调用时间:{}",end-start);
        if (workerBO!=null){
            //封装
            // area
            List<WorkerAreaBO> areas=getWorkerAreaByUserId(userId);
            // category
            List<WorkerCategoryBO> categories=getWorkerCategoryByUserId(userId);
            //查询账户 dubbo远程调用
            AccountDTO accountDTO = accountApi.getAccountByUserId(userId);
            AccountBO accountBO=new AccountBO();
            accountBO.setTotalAmount(accountDTO.getTotalAmount());
            //查询图片 list
            List<AttachInfoBO> attaches=getWorkerAttach(BYZ_TYPE,workerBO.getId());
            //封装到workerBo
            workerBO.setAccountBO(accountBO);
            workerBO.setAttachInfoBOList(attaches);
            workerBO.setWorkerAreaBOList(areas);
            workerBO.setWorkerCategoryBOList(categories);
        }
        return workerBO;
    }

    /**
     * dubbo远程调用attach get查询的接口
     * @param byzType
     * @param id
     * @return
     */
    private List<AttachInfoBO> getWorkerAttach(Integer byzType, Long id) {
        //1. 封装查询参数
        AttachQuery attachQuery=new AttachQuery();
        attachQuery.setBusinessId(id.intValue());
        attachQuery.setBusinessType(byzType);
        List<AttachDTO> attachDTOS = attachApi.getAttachInfoByParam(attachQuery);
        //2. 解析和转化DTO 称为BO
        //在DTO对象里只有图片文件名称fileUuid,其它属性都咩有关系
        //只能手动拼接 http://localhost:8092/static/{fileUuid}
        List<AttachInfoBO> attaches=new ArrayList<>();
        if (attachDTOS == null || attachDTOS.size() == 0 ){
            log.info("远程调用获取师傅图片为空");
            return attaches;
        }else {
            for (AttachDTO attachDTO : attachDTOS) {
                AttachInfoBO attachInfoBO=new AttachInfoBO();
                attachInfoBO.setUrl("http://localhost:8092/static/"+attachDTO.getFileUuid());
                attaches.add(attachInfoBO);
            }
            return attaches;
        }

    }

    private List<WorkerCategoryBO> getWorkerCategoryByUserId(Long userId) {
        //仓储层调用 接口方法
        return workerCategoryRepository.getWorkerCategoriesByUserId(userId);
    }

    private List<WorkerAreaBO> getWorkerAreaByUserId(Long userId) {
        return workerAreaRepository.getWorkerAreasByUserId(userId);
    }

    private WorkerBO getWorkerByUserId(Long userId) {
        return workerRepository.getWorkerByUserId(userId);
    }

    public WorkerDTO queryAreasAndCatsByUserId(Long userId) {
        List<WorkerAreaBO> workerAreas = this.getWorkerAreaByUserId(userId);
        List<WorkerCategoryBO> workerCats = this.getWorkerCategoryByUserId(userId);
        List<Long> areaIds=new ArrayList<>();
        List<Long> catIds=new ArrayList<>();
        if (workerAreas !=null && workerAreas.size()>0){
            for (WorkerAreaBO workerArea : workerAreas) {
                areaIds.add(workerArea.getAreaId());
            }
        }
        if (workerCats!=null && workerCats.size()>0){
            for (WorkerCategoryBO workerCat : workerCats) {
                catIds.add(workerCat.getCategoryId());
            }
        }
        WorkerDTO workerDTO=new WorkerDTO();
        workerDTO.setAreaIds(areaIds);
        workerDTO.setOrderCategoryIds(catIds);
        return workerDTO;
    }
}
